package com.zzy.common.exception;


import com.zzy.common.domain.ParameterErrorBack;
import com.zzy.common.domain.RI;
import com.zzy.common.finalfied.ResultCode;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ValidationException;
import java.util.List;

/**
 * @author zhuZhaoYang
 * @date 2021/7/11 22:33
 */
@RestControllerAdvice(value = {"com.zzy"})
public class GlobalExceptionHandler {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RI parameterExceptionHandler(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        if (bindingResult.hasErrors()) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            if (allErrors.size() != 0) {
                FieldError objectError = (FieldError) allErrors.get(0);
                return new ParameterErrorBack(objectError.getDefaultMessage());
            }
        }
        return new ParameterErrorBack("error");
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BotException.class)
    public RI parameterExceptionHandler2(BotException e) {
        return new ParameterErrorBack(e.getResultCode(), e.getResultMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ValidationException.class)
    public RI parameterValidationException(ValidationException e) {
        return new ParameterErrorBack(ResultCode.PARAMETER_ERROR, e.getMessage());
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(AuthenticationException.class)
    public RI authenticationExceptionHandler(AuthenticationException e) {
        if (e instanceof UnknownAccountException) {
            return new ParameterErrorBack(ResultCode.ACCOUNT_UNKNOWN, e.getMessage());
        } else if (e instanceof IncorrectCredentialsException) {
            return new ParameterErrorBack(ResultCode.LOGIN_USERNAME_OR_PASSWORD_ERROR,
                    "用戶名或者密码错误");
        } else if (e instanceof LockedAccountException) {
            return new ParameterErrorBack(ResultCode.ACCOUNT_FREEZE, e.getMessage());
        } else {
            return new ParameterErrorBack(ResultCode.ACCOUNT_FREEZE, "账户验证失败");
        }
    }

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(AuthorizationException.class)
    public RI authorizationExceptionHandler(AuthorizationException e) {
        if (e instanceof UnauthorizedException) {
            return new ParameterErrorBack(ResultCode.ACCOUNT_NO_PERMISSION, "没有权限");
        } else if (e instanceof UnauthenticatedException) {
            return new ParameterErrorBack(ResultCode.LOGIN_TIME_OUT, "请先登录");
        } else {
            throw new BotException(ResultCode.UNKNOWN_ERROR, "未知错误");
        }
    }


}
